/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2021 NXP
 * All rights reserved.
 *
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#ifndef _APP_H_
#define _APP_H_
#include "fsl_flexspi.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/
/*${macro:start}*/
#define EXAMPLE_FLEXSPI                 FLEXSPI
#define FLASH_SIZE                      0x2000 /* 64Mb/KByte */ /* 填NOR的大小即可，*/
#define EXAMPLE_FLEXSPI_AMBA_BASE       FlexSPI_AMBA_BASE
#define NAND_FLASH_PAGE_SIZE            2048   
#define NOR_FLASH_PAGE_SIZE             256
#define EXAMPLE_SECTOR                  0
#define SECTOR_SIZE                     0x1000 /* 4K */
#define EXAMPLE_FLEXSPI_CLOCK           kCLOCK_FlexSpi
#define NAND_FLASH_PORT                 kFLEXSPI_PortB1
#define NOR_FLASH_PORT                  kFLEXSPI_PortA1
#define EXAMPLE_FLEXSPI_RX_SAMPLE_CLOCK kFLEXSPI_ReadSampleClkLoopbackInternally

#define NAND_CMD_LUT_SEQ_IDX_READ_NORMAL        0
#define NAND_CMD_LUT_SEQ_IDX_PAGE_READ          1
#define NAND_CMD_LUT_SEQ_IDX_WRITEENABLE        2
#define NAND_CMD_LUT_SEQ_IDX_ERASESECTOR        3
#define NAND_CMD_LUT_SEQ_IDX_PAGEPROGRAM_LOAD   4
#define NAND_CMD_LUT_SEQ_IDX_PAGEPROGRAM_EXE    5
#define NAND_CMD_LUT_SEQ_IDX_WRITESTATUSREG     6
#define NAND_CMD_LUT_SEQ_IDX_READSTATUSREG      7

#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD     8
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS         9
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE        10
#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR        11
#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD   12
#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG     13
#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG      14
#define NOR_CMD_LUT_SEQ_IDX_ERASECHIP          15

#define CUSTOM_LUT_LENGTH        64
#define FLASH_QUAD_ENABLE        0x02
#define FLASH_BUSY_STATUS_POL    1
#define FLASH_BUSY_STATUS_OFFSET 0
#define CACHE_MAINTAIN           1

/*${macro:end}*/

/*******************************************************************************
 * Variables
 ******************************************************************************/
/*${variable:start}*/
#if (defined CACHE_MAINTAIN) && (CACHE_MAINTAIN == 1)
typedef struct _flexspi_cache_status
{
    volatile bool DCacheEnableFlag;
    volatile bool ICacheEnableFlag;
} flexspi_cache_status_t;
#endif
/*${variable:end}*/

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
/*${prototype:start}*/
void BOARD_InitHardware(void);

static inline void flexspi_clock_init(void)
{
    const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};

    CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
    CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24);   /* Set PLL3 PFD0 clock 360MHZ. */
    CLOCK_SetMux(kCLOCK_FlexspiMux, 0); /* Choose PLL3 PFD0 clock as flexspi source clock. */
    CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3);   /* flexspi clock 120M. */
}
/*${prototype:end}*/
extern flexspi_device_config_t nor_deviceconfig;
extern flexspi_device_config_t nand_deviceconfig;


extern uint32_t customLUT[CUSTOM_LUT_LENGTH];

extern void flexspi_nand_disable_cache(flexspi_cache_status_t *cacheStatus);
extern void flexspi_nand_enable_cache(flexspi_cache_status_t cacheStatus);

extern status_t flexspi_nand_flash_erase_sector(FLEXSPI_Type *base, uint32_t address);
extern status_t flexspi_nand_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src);
extern status_t flexspi_nand_get_vendor_id(FLEXSPI_Type *base, uint32_t *vendorId);
extern status_t flexspi_nand_enable_quad_mode(FLEXSPI_Type *base);
extern status_t flexspi_nand_erase_chip(FLEXSPI_Type *base);
extern void flexspi_flash_port_init(FLEXSPI_Type *base,flexspi_port_t port);

extern status_t flexspi_nand_get_status(FLEXSPI_Type *base, uint8_t addr, uint8_t *reg_status);
extern status_t flexspi_nand_page_data_read(FLEXSPI_Type *base, uint16_t pageAddr, uint8_t *data);
extern status_t flexspi_nand_page_data_quad_read(FLEXSPI_Type *base, uint16_t pageAddr, uint8_t *data);
extern status_t flexspi_nand_set_status(FLEXSPI_Type *base, uint8_t addr, uint8_t reg_status);

extern void flexspi_nand_flash_init(FLEXSPI_Type *base);

/* 以下是nor的操作函数 */
extern status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address);
extern status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src);
extern status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId);
extern status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base);
extern status_t flexspi_nor_erase_chip(FLEXSPI_Type *base);

extern void FlexSpi_Port_Reset(flexspi_port_t port);

#endif /* _APP_H_ */
